/**
 * Copyright (c) 2022 Presto Labs Pte. Ltd.
 * Author: Ju
 */

#include "coin2/base/influxdb/influxdb_builder.h"

#include <glog/logging.h>

#include <utility>
namespace coin2::base::influxdb {

LineProtocol::LineProtocol(const LineProtocol &rhs) {
  header = rhs.header;
  if (rhs.buffer) {
    buffer = new BigFieldsType(*rhs.buffer);
  }
  ts = rhs.ts;
}

LineProtocol::LineProtocol(LineProtocol &&rhs) {
  header = std::move(rhs.header);
  buffer = rhs.buffer;
  rhs.buffer = nullptr;
  ts = rhs.ts;
}

LineProtocol::~LineProtocol() {
  if (buffer != nullptr) {
    delete buffer;
  }
}

std::string Builder::Escape(const std::string &s) {
  std::string res;
  char backslash = '\\';

  for (auto i : s) {
    switch (i) {
      case '"': {
        res.push_back(backslash);
        [[fallthrough]];
      }
      default:
        res.push_back(i);
    }
  }
  return res;
}

void Builder::Reset() {
  fields_ = std::unordered_map<std::string, std::string>();
  if (!freeze_) {
    tags_.clear();
  }
}

std::string Builder::BuildHeader() {
  std::ostringstream os;
  os << measurement_;
  for (const auto &tag : tags_) {
    os << "," << tag.first << "=" << tag.second;
  }
  return os.str();
}

void Builder::Freeze() {
  freeze_ = true;
  header_.reset(new std::string(BuildHeader()));
  LOG(INFO) << "Influx Build Freeze meas and header to data: " << *header_;
}

LineProtocol Builder::Build() {
  LineProtocol line;
  if (freeze_) {
    line.header = header_;
  } else {
    line.header.reset(new std::string(BuildHeader()));
  }
  if (ts_ == kInitialTs) {
    line.ts = impl::GetCurrentTimestamp();
  } else {
    line.ts = ts_;
  }
  line.buffer = new BigFieldsType(std::move(fields_));

  Reset();

  return line;
}

Builder &Builder::Tag(const std::string &key, std::string v) {
  tags_[Escape(key)] = Escape(v);
  return *this;
}

}  // namespace coin2::base::influxdb
